package com.nidu.demo.i18n.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.exception.BizException;
import com.nidu.demo.common.exception.ErrorCodeConstants;
import lombok.NonNull;
import org.jetbrains.annotations.NotNull;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class I18nLocaleResolver implements LocaleResolver {

    public Map<String, Locale>  getSupportedLanguages(){
        Map<String, Locale> languages = new HashMap<>();
        languages.put("zh-CN", Locale.SIMPLIFIED_CHINESE);
        languages.put("en-US", Locale.US);
        return languages;
    }

    /**
     * 获取当前请求的 Locale
     * 线程安全的方式获取当前请求
     */
    public Locale getLocal() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            return resolveLocale(request);
        }
        return Locale.getDefault();
    }

    /**
     * 从HttpServletRequest中获取Locale
     * 支持多种方式获取语言信息：
     * 1. URL参数 lang
     * 2. Header Accept-Language
     * 3. Session中的语言设置
     *
     * @param request HTTP请求
     * @return 语言环境
     */
    @NotNull
    @Override
    public Locale resolveLocale(@NotNull HttpServletRequest request) {

        // 1. 优先从URL参数获取
        String language = request.getParameter("lang");
        if (StrUtil.isNotBlank(language)) {
            return parseLocale(language);
        }

        // 2. 从Session获取
        Object sessionLocale = request.getSession().getAttribute("locale");
        if (sessionLocale instanceof Locale) {
            return (Locale) sessionLocale;
        }

        // 3. 从Header获取
        String acceptLanguage = request.getHeader("Accept-Language");
        if (StrUtil.isNotBlank(acceptLanguage)) {
            // 取第一个语言
            String firstLang = acceptLanguage.split(",")[0].trim();
            if (firstLang.contains("-") || firstLang.contains("_")) {
                return parseLocale(firstLang);
            }
        }

        // 4. 使用默认语言环境
        return Locale.getDefault();
    }

    /**
     * 解析语言字符串为Locale对象
     * 支持格式：zh-CN, zh_CN, en-US, en_US
     */
    public Locale parseLocale(String language) {
        String normalizedLang = language.trim().replace("_", "-");
        String[] parts = normalizedLang.split("-");

        if (parts.length >= 2) {
            return new Locale(parts[0], parts[1]);
        } else if (parts.length == 1) {
            return new Locale(parts[0]);
        } else {
            throw new BizException(ErrorCodeConstants.I18N_LOCATE_PARSE_FAIL.getCode(), ErrorCodeConstants.I18N_LOCATE_PARSE_FAIL.getMessage());
        }
    }

    /**
     * 设置Locale到Session中
     * 用于实现Locale的切换和持久化
     *
     * @param request  HTTP请求
     * @param response HTTP响应
     * @param locale   要设置的语言环境
     */
    @Override
    public void setLocale(@NonNull HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) {
        if (locale != null) {
            request.getSession().setAttribute("locale", locale);
        }
    }

}

